package com.jic.order.controller.callback;

import com.alibaba.fastjson.JSONObject;
import com.jic.common.base.vo.RestResult;
import com.jic.order.api.CardOrderApi;
import com.jic.order.entity.Order;
import com.jic.order.entity.OrderPay;
import com.jic.order.entity.OrderPayDetail;
import com.jic.order.mapper.OrderMapper;
import com.jic.order.mapper.OrderPayMapper;
import com.jic.order.request.OrderAuditRequest;
import com.jic.order.request.base.CardCouponPlatformRequest;
import com.jic.order.service.*;
import com.jic.order.utils.DatagramEncDec;
import com.jic.order.utils.XmlUtils;
import com.jic.product.after.api.ProductListApi;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.util.*;

@Slf4j
@Api(tags = {"支付回调"})
@RequestMapping(value = "callback")
@RestController
public class CallBackController {
    @Autowired(required = false)
    private OrderPayMapper orderPayMapper;
    @Autowired
    private OrderParentService orderParentService;
    @Autowired
    private OrderPayDetailService orderPayDetailService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private ProductListApi productListApi;

    @Autowired
    private CardOrderApi cardOrderApi;

    @Autowired
    private OrderGoodsService orderGoodsService;

    @Autowired
    private OrderOperateService orderOperateService;

    @Autowired
    private OrderMapper orderMapper;

    @ApiOperation(value = "微众支付回调")
    @PostMapping("/wzPay")
    public JSONObject wzPay(@RequestBody JSONObject callParam) {
        log.info("微众支付回调{}", callParam);
        String wbapAtsOrderNo = callParam.getString("wbapAtsOrderNo");
        BigDecimal amount = callParam.getBigDecimal("amount");
        String transStatus = callParam.getString("transStatus");
        String orderNo = callParam.getString("orderNo");
        String payType = callParam.getString("payType");
        String merchantId = callParam.getString("merchantId");
        updateStatus(orderNo, amount, wbapAtsOrderNo);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("code", "0");
        jsonObject.put("msg", "成功");
        return jsonObject;
    }


    @ResponseBody
    @RequestMapping("/wxPay")
    @ApiOperation(value = "微信支付回调")
    public void callbackPayResult(HttpServletRequest request, HttpServletResponse response) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader((ServletInputStream) request.getInputStream()));
        String line = null;
        StringBuilder sb = new StringBuilder();
        while ((line = br.readLine()) != null) {
            sb.append(line);
        }
        br.close();
        //sb为微信返回的xml
        String notityXml = sb.toString();
        log.info("接收到的报文：" + notityXml);
        try {
            notityXml = wxCallbackNotify(notityXml);
            log.info("同步通知微信报文:" + notityXml);
        } catch (Exception e) {
            log.warn("微信支付回调失败参数失败");
            e.printStackTrace();
        }
        BufferedOutputStream out = new BufferedOutputStream(
                response.getOutputStream());
        out.write(notityXml.getBytes());
        out.flush();
        out.close();
    }


    private String wxCallbackNotify(String xmlResult) throws Exception {
        String success = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
                + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
        String fail = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
                + "<return_msg><![CDATA[please again]]></return_msg>" + "</xml> ";
        Map<String, String> map = XmlUtils.doXMLParse(xmlResult);
        String wxSign = map.get("sign");
        map = paraFilter(map);
        String key = "bc7230deeb01a357ccd249c714b41d4c";
        String validStr = createLinkString(map);//把数组所有元素，按照“参数=参数值”的模式用“&”字符拼接成字符串
        validStr = validStr + "&key=" + key;
        String sign = DatagramEncDec.sign(validStr, "UTF-8");
        log.info("解密结果:{}", sign.equals(wxSign));
        log.info("return_code:{}", map.get("return_code"));
        if ("SUCCESS".equals(map.get("return_code")) && sign.equals(wxSign)) {
            //Integer money = ;
            BigDecimal money = BigDecimal.valueOf(Integer.valueOf(map.get("total_fee")) / 100);
            log.info("微信回调金额为:" + money);
            //订单编号
            String out_trade_no = map.get("out_trade_no");
            updateStatus(out_trade_no, money, out_trade_no);
            return success;
        }
        return fail;
    }


    private void updateStatus(String orderNo, BigDecimal amount, String wbapAtsOrderNo) {
        JSONObject parentOrder = orderParentService.queryOrderParentByOrderNo(orderNo);
        List<JSONObject> mOrders = orderService.queryOrderByOrderNo(orderNo);
        JSONObject payOrder = orderPayMapper.queryStepByParentOrderNo(orderNo);
        String order_pay_no = payOrder.getString("order_pay_no");
        BigDecimal orderAmount = parentOrder.getBigDecimal("actual_pay_total_amount");
        if (orderAmount.compareTo(amount) != 0) {
            //如果金额不一致
        }
        //修改父订单为支付成
//        OrderParent parent = new OrderParent();
//        parent.setParentOrderNo(orderNo);
//        parent.setOrderStatus(3);//已支付
//        parent.setId(parentOrder.getLong("id"));
//        orderParentService.update(parent);
        //主订单修改为成功
        JSONObject parm = new JSONObject();
        parm.put("status", 3);
        parm.put("parentOrderNo", orderNo);
        orderService.updateByOrderNo(parm);
        //修改支付订单
        OrderPay orderPay = new OrderPay();
        orderPay.setParentOrderNo(orderNo);
        orderPay.setPayStatus(3);
        orderPayMapper.update(orderPay);
        //修改详细支付订单
        OrderPayDetail orderPayDetail = new OrderPayDetail();
        orderPayDetail.setOrderPayNo(order_pay_no);
        orderPayDetail.setWzStep(3);
        orderPayDetail.setPayReceiptNo(wbapAtsOrderNo);
        orderPayDetail.setPayStatus(2);
        orderPayDetailService.update(orderPayDetail);

        List<Order> orderList = orderMapper.query(new Order() {{
            setParentOrderNo(order_pay_no);
        }});
        //订单默认审核通过
        if(CollectionUtils.isNotEmpty(orderList)){
            OrderAuditRequest request = new OrderAuditRequest();
            request.setAuditStatus(1);
            request.setOrderNo(orderList.get(0).getOrderNo());
            orderOperateService.audit(request);
        }
        //支付成功以后判断是否有虚拟商品
        String ids = "";
        for (JSONObject mOrder : mOrders) {
            ids += mOrder.getLongValue("id") + ",";
        }
        ids = ids.substring(0, ids.length() - 1);
        //商品
        List<JSONObject> productList = productListApi.queryGoodsTypeById(ids);
        //type:商品类型:1-常规商品;2卡券、3海购、4赠品、10实体卡、11虚拟卡、20券、 5生鲜产品、6增值服务、7其他、21积分商品;31-称重商品;)
        for (JSONObject product : productList) {
            Integer type = product.getInteger("type");
            switch (type) {
                case 2:
                    buyCard(product, orderNo);
                case 11:
                    buyCard(product, orderNo);
                case 41:
                    buyCard(product, orderNo);
            }
        }
    }

    private void buyCard(JSONObject cardParam, String parentNo) {
        String card_order_no = UUID.randomUUID().toString().replaceAll("-", "");
        CardCouponPlatformRequest cardRequest = new CardCouponPlatformRequest();
        cardRequest.setMerchantId("WEM202011230036116");
        cardRequest.setCardId(cardParam.getString("code"));
        cardRequest.setMerchantOrderNo(card_order_no);
        cardRequest.setQuantity(1);
        cardRequest.setMerchantId("100000");
        cardRequest.setMemberNo(System.currentTimeMillis() + "");
        RestResult<?> ret = cardOrderApi.addCardCouponPlatform(cardRequest);
        log.info("卡券下单{}", ret);
        JSONObject card = (JSONObject) ret.getData();
        JSONObject content = card.getJSONObject("content");
        String code = content.getString("code");
        Integer card_status = 2;
        String card_msg = content.getString("msg");
        if (!"0".equals(code)) {
            //退款,更新为失败
            card_status = 0;
        }
        JSONObject result = content.getJSONObject("result");
        String wzOrderNo = result.getString("orderNo");
        //商品订单id
        Long orderGoodId = orderParentService.queryGoodByOrderNo(parentNo);
        //根据id更新
        content.clear();
        content.put("card_order_no", card_order_no);
        content.put("card_id", cardParam.getString("code"));
        content.put("card_status", card_status);
        content.put("id", orderGoodId);
        content.put("card_msg", card_msg);
        orderGoodsService.updateWzCardNo(content);
        content.clear();
        card.clear();
        log.info("卡券下单:{}", card);
    }

    /**
     * 除去数组中的空值和签名参数
     *
     * @param sArray 签名参数组
     * @return 去掉空值与签名参数后的新签名参数组
     */
    private Map<String, String> paraFilter(Map<String, String> sArray) {
        Map<String, String> result = new HashMap<String, String>();
        if (sArray == null || sArray.size() <= 0) {
            return result;
        }
        for (String key : sArray.keySet()) {
            String value = sArray.get(key);
            if (value == null || value.equals("") || key.equalsIgnoreCase("sign")
                    || key.equalsIgnoreCase("sign_type")) {
                continue;
            }
            result.put(key, value);
        }
        return result;
    }


    private String createLinkString(Map<String, String> params) {
        List<String> keys = new ArrayList<String>(params.keySet());
        Collections.sort(keys);
        String prestr = "";
        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            String value = params.get(key);
            if (i == keys.size() - 1) {// 拼接时，不包括最后一个&字符
                prestr = prestr + key + "=" + value;
            } else {
                prestr = prestr + key + "=" + value + "&";
            }
        }
        return prestr;
    }

}
